using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace Charisma.Conventions
{
    public sealed class ConventionSet : IEnumerable<IConvention>
    {
        private HashSet<IConvention> conventions;

        public ConventionSet()
        {
            conventions = new HashSet<IConvention>();

            Add(new PublicRepositoryConvention());
            Add(new PublicMemberConvention());
            Add(new NamedKeyMemberConvention());
        }

        public void Add<TConvention>(TConvention convention) where TConvention : IConvention
        {
            Contract.Requires(convention != null);

            conventions.Add(convention);
        }

        public IEnumerable<TConvention> Get<TConvention>() where TConvention : IConvention
        {
            return conventions
                .Where(c => c is TConvention)
                .Cast<TConvention>();
        }

        public void Remove<TConvention>() where TConvention : IConvention
        {
            if (conventions.Count == 0)
                return;

            conventions.RemoveWhere(c => c is TConvention);
        }

        public void Clear()
        {
            conventions.Clear();
        }

        public IEnumerator<IConvention> GetEnumerator()
        {
            return conventions.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}